package cn.tedu.csmall.server.service.impl;
 /*
 @Time: 2022/8/25 8:25
 @Author:GShuai
 @File:CategoryService.class
 @Software:IntelliJ IDEA
*/

import cn.tedu.csmall.server.ex.ServiceException;
import cn.tedu.csmall.server.mapper.CategoryMapper;
import cn.tedu.csmall.server.pojo.dto.CategoryAddNewDTO;
import cn.tedu.csmall.server.pojo.eneity.Category;
import cn.tedu.csmall.server.pojo.vo.CategoryDetailVO;
import cn.tedu.csmall.server.pojo.vo.CategoryListItemVO;
import cn.tedu.csmall.server.repo.ICategoryRepository;
import cn.tedu.csmall.server.service.ICategoryService;
import cn.tedu.csmall.server.web.ServiceCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 类别业务实现
 *
 * @version 0.0.1
 */
@Service
@Slf4j
public class CategoryServiceImpl implements ICategoryService {

    @Autowired
    private ICategoryRepository categoryRepository;
    @Autowired
    private CategoryMapper categoryMapper;

    public CategoryServiceImpl() {
        log.debug("创建业务逻辑对象：CategoryServiceImpl");
    }

    @Override
    public void addNew(CategoryAddNewDTO categoryAddNewDTO) {
        log.debug("开始处理添加类别的业务，参数：{}", categoryAddNewDTO);
        // 获取参数中的parentId
        Long parentId = categoryAddNewDTO.getParentId();
        // 如果parentId不为0，调用Mapper对象的getById()方法，查询父级类别
        CategoryDetailVO parentCategory = null;
        if (parentId != 0) {
            parentCategory = categoryMapper.getById(parentId);
            // 判断父级类别是否存在，如果不存在，抛出异常
            if (parentCategory == null) {
                String message = "添加类别失败，父级别不存在！";
                log.error(message);
                throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
            }
        }
        // 检查此类别（尝试创建的类别）的名称有没有被使用
        // 如果已经被使用，则不允许创建
        String name = categoryAddNewDTO.getName();
        int count = categoryMapper.countByName(name);
        if (count > 0) {
            String message = "添加类别失败，类别名称【" + name + "】已经被占用！";
            log.error(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }
        // 创建实体对象（Mapper的方法的参数是实体类型）
        Category category = new Category();

        // 将当前方法参数的值复制到Brand实体类型的对象中
        BeanUtils.copyProperties(categoryAddNewDTO, category);
        // 补全属性值（不由客户端提交的属性的值，应该在插入之前补全）
        // 在父级类别的深度上加1，如果无父级，则值就是1
        if (parentId == 0) {
            category.setDepth(1);
        } else {
            category.setDepth(parentCategory.getDepth() + 1);
        }
        // 此时是添加新的类别，此类别此时不会有子级，所以isParent此时固定为0
        category.setIsParent(0);

        // 将类别数据写入到数据库中
        log.debug("即将向表中写入数据：{}", category);
        int rows = categoryMapper.insert(category);
        if (rows != 1) {
            String message = "添加类别失败，服务器忙，请稍后再次尝试！【错误码：1】";
            log.error(message);
            throw new ServiceException(ServiceCode.ERR_INSERT, message);
        }

        // 先在CategoryMapper中实现updateById()
        // 如果parentId不为0，且父级类别的isParent为0（parentCategory.getIsParent() == 0）
        // && parentCategory.getIsParent() != null 为了防止IsParent被漏掉》》》》》  <result column="is_parent" property="isParent" />
        if (parentId != 0 && parentCategory.getIsParent() != null && parentCategory.getIsParent() == 0) {
            // 调用updateById()将父级类别的isParent改为1M
            // 注意：当前业务方法应该是事务性的
            Category c = new Category();
            c.setId(parentId);
            c.setIsParent(1);
            rows = categoryMapper.updateById(c);
            if (rows != 1) {
                String message = "添加类别失败，服务器忙，请稍后再次尝试！【错误码：2】";
                log.error(message);
                throw new ServiceException(ServiceCode.ERR_INSERT, message);
            }
        }
    }

    @Override
    public void deleteById(Long id) {
        log.debug("开始处理删除类别的业务，id={}", id);
        // 根据id查询数据
        CategoryDetailVO queryResult = categoryMapper.getById(id);
        // 判断查询结果是否为null
        if (queryResult == null) {
            // 抛出异常
            String message = "删除类别失败，尝试删除的数据（id=" + id + "）不存在！";
            log.error(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 检查当前类别是否存在子级类别
        // {} 里面写代码  变成局部变量
        {
            int count = categoryMapper.countByParentId(id);
            if (count > 0) {
                // 抛出异常
                String message = "删除类别失败，当前类别仍存在子类别，不能删除！";
                log.error(message);
                throw new ServiceException(ServiceCode.ERR_DELETE, message);
            }
        }

        // 调用mapper对象执行删除，并获取返回值
        int rows = categoryMapper.deleteById(id);
        // 判断返回值是否不为1
        if (rows != 1) {
            // 抛出异常
            String message = "删除类别失败，服务器忙，请稍后再次尝试！【错误码：1】";
            log.error(message);
            throw new ServiceException(ServiceCode.ERR_DELETE, message);
        }

        // 根据此前的检查结果即可得到parentId（然后，判断父级类别是否存在，可以省略）
        Long parentId = queryResult.getParentId();

        // 开发Mapper层：根据父级类别id统计子级类别的数量
        int count = categoryMapper.countByParentId(parentId);

        // 检查是否有必要将父级类别的isParent改为0
        // 判断：统计当前类别的父级类别有多少个子级，判断是否等于0
        if (count == 0) {
            // 将父级类别的isParent改为0
            Category category = new Category();
            category.setId(parentId);
            category.setIsParent(0);
            rows = categoryMapper.updateById(category);
            // 判断返回值是否不为1
            if (rows != 1) {
                // 抛出异常
                String message = "删除类别失败，服务器忙，请稍后再次尝试！【错误码：2】";
                log.error(message);
                throw new ServiceException(ServiceCode.ERR_DELETE, message);
            }
        }
    }

    @Override
    public List<CategoryListItemVO> listByParentId(Long parentId) {
        return categoryMapper.listByParentId(parentId);
    }
}
